package com.quotes.charts;

import java.awt.*;
import javax.swing.*;
import org.jfree.chart.*;
import org.jfree.chart.plot.*;
import org.jfree.data.time.*;
import org.jfree.data.xy.*;
import org.jfree.chart.axis.*;
import org.jfree.chart.labels.*;
import org.jfree.chart.renderer.xy.*;
import com.quotes.datamodell.*;
import com.quotes.datamodell.TimeSeries;
import com.quotes.dates.TimeRange;

public class CandleStickChart extends JPanel 
{
	private static final long serialVersionUID = 1L;
	private Quotes quotes = null;
	private TimeRange range = null;
	private TimeSeries openPrices = null;
	private TimeSeries closePrices = null;
	private TimeSeries highPrices = null;
	private TimeSeries lowPrices = null;
	private TimeSeries volumes = null;
	
	public CandleStickChart(Quotes quotes, TimeRange range) {
		this.quotes = quotes;
		this.range = range;

		this.openPrices = quotes.getQuote(QuotesType.OPEN).extract(range);
		this.closePrices = quotes.getQuote(QuotesType.CLOSE).extract(range);
		this.highPrices = quotes.getQuote(QuotesType.HIGH).extract(range);
		this.lowPrices = quotes.getQuote(QuotesType.LOW).extract(range);
		this.volumes = quotes.getQuote(QuotesType.VOLUME).extract(range);
	
		XYPlot plot = createPlot();
		ChartPanel chartPanel = createChartPanel(plot);
        
        this.setLayout(new BorderLayout());
		this.add(chartPanel, BorderLayout.CENTER);
	}

	private XYPlot createPlot() {
		DefaultHighLowDataset hlDataset = createHighLowDataset();
        XYDataset xyDataset = createXyDataset();
        XYPlot plot = createPlot(hlDataset, xyDataset);
        return plot;
	}

	private ChartPanel createChartPanel(XYPlot plot) {
		JFreeChart chart = new JFreeChart(plot);
        ChartPanel chartPanel = new ChartPanel(chart);
		return chartPanel;
	}
	
    private XYPlot createPlot(DefaultHighLowDataset hlDataset, XYDataset xyDataset) {
    	DateAxis domainAxis = createDateAxis();
        NumberAxis rangeAxis = createNumberAxis();
        
        CandlestickRenderer renderer = new CandlestickRenderer(4, false, new HighLowItemLabelGenerator());
    	XYPlot plot = new XYPlot(hlDataset, domainAxis, rangeAxis, renderer);
    	XYLineAndShapeRenderer lineRenderer = new XYLineAndShapeRenderer(true, false);
    	plot.setDataset(1, xyDataset);
    	plot.setRenderer(1, lineRenderer);
        
        return plot;
    }
    
    private double getLowestPrice() {
    	return lowPrices.getMinValue() * 0.95;
    }
    
    private double getHighesPrice() {
    	return highPrices.getMaxValue() * 1.05;
    }

	private NumberAxis createNumberAxis() {
		NumberAxis rangeAxis = new NumberAxis();
        rangeAxis.setStandardTickUnits(NumberAxis.createStandardTickUnits());
        rangeAxis.setRange(getLowestPrice(), getHighesPrice());
		return rangeAxis;
	}

	private DateAxis createDateAxis() {
		DateAxis domainAxis = new DateAxis();
        domainAxis.setAutoRange(true);
        domainAxis.setTickLabelsVisible(true);
        domainAxis.setAutoTickUnitSelection(true);
		return domainAxis;
	}
	
	private DefaultHighLowDataset createHighLowDataset() {
		DefaultHighLowDataset result = new DefaultHighLowDataset(
				quotes.getSymbol().getYahooName(),
				openPrices.DatesAsArray(), 
				highPrices.ValuesAsArray(),
				lowPrices.ValuesAsArray(), 
				openPrices.ValuesAsArray(), 
				closePrices.ValuesAsArray(),
				volumes.ValuesAsArray());
		
		return result;
    }
	    
	private XYDataset createXyDataset() {
		TimeSeriesCollection data = new TimeSeriesCollection();

//		TimeSeries maxPrices = TimeSeriesCalculator.calculateMovingMaximum(quotes.getQuote("high"), 20).extractPeriod(range);
//		data.addSeries(maxPrices.convertToChartTimeSeries("EMAShort"));
		
		return data;
	}
}
